/*
 * VS1053B_Common.c
 *
 *  Created on: 2021年4月12日
 *      Author: slh95
 */
#include "VS1053B_Config.h"
#include "VS1053B_Common.h"
#include "spi.h"
#include "main.h"
#include <stdio.h>

void VS1053B_PIN_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	DREQ_PIN_EN();
	XCS_PIN_EN();
	XDCS_PIN_EN();
	XRESET_PIN_EN();

	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Pin = DREQ_PIN;
	HAL_GPIO_Init(DREQ_PORT, &GPIO_InitStruct);

	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

	GPIO_InitStruct.Pin = XCS_PIN;
	HAL_GPIO_Init(XCS_PORT, &GPIO_InitStruct);
	GPIO_InitStruct.Pin = XDCS_PIN;
	HAL_GPIO_Init(XDCS_PORT, &GPIO_InitStruct);
	GPIO_InitStruct.Pin = XRESET_PIN;
	HAL_GPIO_Init(XRESET_PORT, &GPIO_InitStruct);

	XCS_DIS();
	XDCS_DIS();
}

/*
 *	VS1053B低速SPI写函数
 *	参数：
 *		cmd: 读或者写的指令， 读-0x03, 写-0x02
 *		addr: VS1053B的寄存器地址
 *		w_data: 配置寄存器的值
 *	返回值：
 *		ret：读到该寄存器的高十六位，根据时许知道，高十六位代表的是读到的数据
 *	说明：这是在SPI频率为4.5MHz情况下的读写函数封装，一次读写一个word，也就是4bytes
 */
uint16_t VS1053B_SPI_LowFreq_ReadWrite(uint8_t cmd, uint8_t addr, uint16_t w_data)
{
	uint16_t ret = 0;
	uint16_t instruction = cmd | (addr<<8);
	uint32_t w_buf = instruction | (w_data<<16);
	uint32_t r_buf = 0;

	while(DREQ() == 0);

	XDCS_EN();
	XCS_EN();

	HAL_SPI_TransmitReceive(&hspi2, (uint8_t*)&w_buf, (uint8_t*)&r_buf, 4, 300);
	ret = r_buf>>16;

	XCS_DIS();
	return ret;
}

uint8_t VS1053B_HardReset(void)
{
	uint16_t retry = 0;
	XRESET_LOW();
	HAL_Delay(20);
	XDCS_EN();
	XCS_DIS();
	XRESET_HIGH();

	while(DREQ()==0 && retry<500)
	{
		retry++;
		HAL_Delay(1);
	}

	HAL_Delay(20);
	if(retry==500)
	{
		return 1;
	}

	return 0;
}

void VS1053B_SPI_Test(void)
{
	uint16_t read_tmp = 0xFFFF;
	uint16_t mode_value = 0;

	printf("\rVS1053B 低速SPI读Mode寄存器测试\n");

	VS1053B_HardReset();
	VS1053B_SPI_LowFreq_ReadWrite(VS1053B_WRITE_CMD, VS1053B_VOL_REG, 0x2020);
	VS1053B_SPI_LowFreq_ReadWrite(VS1053B_WRITE_CMD, VS1053B_MODE_REG, 0x0820);
	while(DREQ() == 0);
	mode_value = VS1053B_SPI_LowFreq_ReadWrite(VS1053B_READ_CMD, VS1053B_MODE_REG, read_tmp);
	printf("\rVS1053B的Mode寄存器的值：0x%4x\n", mode_value);
}
